<?php

namespace App\Service\Pay;

use App\Models\Bank;
use App\Models\Card;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Support\Facades\Http;
use Exception;
use Illuminate\Support\Facades\Log;

class AsiaPayService extends PayService implements Pay
{

    /**
     * 充值通知地址
     * @var string
     */
    protected string $pay_notify_url = '/api/v1/asia_recharge';

    /**
     * 代付通知地址
     * @var string
     */
    protected string $withdrawal_notify_url = '/api/v1/asia_withdrawal';


    //充值
    public function recharge($attach = [])
    {
        try {
            $this->setReturnUrl();
            $param = [
                'merchantNo' => $this->merchant,
                'outTradeNo' => $this->order->no,
                'type' => $this->pay_type,
                'code' => $this->pay_code,
                'amount' => $this->order->amount,
                'timestamp' => time(),
            ];
            $param['sign'] = $this->sign($param, $this->pay_key);
            $param['notifyUrl'] = url($this->pay_notify_url);
            $response = Http::asJson()->post($this->pay_url, $param);
            $result = json_decode($response->body(), true);
            $this->order->param = json_encode($param, JSON_UNESCAPED_UNICODE);
            $this->order->response = json_encode($result, JSON_UNESCAPED_UNICODE);
            //Log::info('asia充值', ['result'=>$result]);
            if (isset($result['code']) && $result['code'] == 200) {
                $this->order->payment_no = $result['message'];
                $this->order->save();
                return $result['data'];
            }
            $this->rechargeFail();
            return false;
        } catch (Exception $exception) {
            $error_message = json_encode(['msg' => $exception->getMessage(), 'file' => $exception->getFile(), 'line' => $exception->getLine()], JSON_UNESCAPED_UNICODE);
            $this->rechargeFail($error_message);
            return false;
        }
    }

    public function withdrawal($attach = [])
    {
        //info('提现订单开始:'.$this->order->no);
        try {
            //$card = json_decode($this->order->card, true);
            $card = Card::query()->where('user_id', '=', $this->order->user_id)->first();
            $bank_code = '';
            $bankname = '';
            if($card['bank_id'] != 0){
                $bank = Bank::getBank($card['bank_id']);
                $bank_code = $bank['asia_code'];
                $bankname = $bank['name'];
            }
            $param = [
                'merchantNo' => $this->merchant,
                'outTradeNo' => $this->order->no,
                'bankCode' => $bank_code,
                'bankCardNumber' => $card->number,
                'amount' => intval($this->order->actual_amount),
                'timestamp' => time(),
                'notifyUrl' => url($this->withdrawal_notify_url),
                'username' => $card->username
            ];

            $param['sign'] = $this->signwin($param, $this->withdrawal_key);
            $response = Http::asJson()->post($this->withdrawal_url, $param);
            //info('提现订单响应:'.$response);
            $result = json_decode($response->body(), true);
            $result = is_array($result) ? $result : [];
            //记录入参跟响应
            $state = isset($result['code']) && $result['code'] == 200 && isset($result['success']) && $result['success'] == true ;
            $this->withdrawalCallback($param, $result, $jsonobj['code'] ?? '', $state);
            $this->order->save();
        } catch (Exception $exception) {
            $this->withdrawalCallback([], ['msg' => $exception->getMessage(), 'file' => $exception->getFile(), 'line' => $exception->getLine()], '', false);
        }
    }


    /**
     * 签名
     * @param $data
     * @param $secret
     * @return string
     */
    protected function sign($param ,$secret): string
    {
        $str = $param['merchantNo'] . "|" . $param['outTradeNo'] . "|" . $param['type'] . "|" . $param['code'] . "|" . $param['amount'] . "|" . $param['timestamp'] . "|" . $secret ."|";
        return md5($str);
    }

    protected function signwin($param ,$secret): string
    {
        $str = $param['merchantNo'] . "|" . $param['outTradeNo'] . "|" . $param['bankCode'] . "|" . $param['bankCardNumber'] . "|" . $param['amount'] . "|" . $param['timestamp'] . "|" . $secret ."|";
        return md5($str);
    }

    /**
     * 验签
     * @param array $params
     * @param string $type
     * @return bool
     */
    public function checkSign(array $params, string $type): bool
    {
        $sign = $params['sign'];
        if($type == 'pay'){
            $str = $params['merchantNo'] . "|" . $params['orderNo']. "|" . $params['outTradeNo'] . "|" . $params['type'] . "|". $params['code'] ."|". $params['amount'] ."|". $params['timestamp'] ."|". $this->pay_key . "|";
            return $sign == md5($str);
        }else{
            $str = $params['merchantNo'] . "|" . $params['orderNo']. "|" . $params['outTradeNo'] . "|" . $params['bankCode'] . "|". $params['bankCardNumber'] ."|". $params['amount'] ."|". $params['timestamp'] . "|". $params['status']."|". $this->withdrawal_key . "|";
            return $sign == md5($str);
        }

        //MD5(merchantNo+"|"+orderNo+"|"+outTradeNo++"|"+bankCode+"|"+bankCardNumber+"|"+amount+"|"+timestamp+"|"+status+”|”+key+"|" )

        // 验证签名参数是否正确
        //unset($params['sign'], $params['signType'], $params['merRetMsg']);
        //return $sign == $this->sign($params['orderid'],$params['amount'], $type == 'pay' ? $this->pay_key : $this->withdrawal_key);
    }

}
